﻿using System;
using System.Collections.Generic;
using SimpleWorkflow.Event;

namespace SimpleWorkflow.Data
{
    public class FlowContext
    {
        internal EventSurrogates EventSurrogates { get; set; }
        private Dictionary<string, IReference> References { get; set; }
        private Dictionary<IReference, object> Values { get; set; }

        public FlowContext()
        {
            EventSurrogates = new EventSurrogates();
            References = new Dictionary<string, IReference>();
            Values = new Dictionary<IReference, object>();
        }

        public T GetValue<T>(IReference reference)
        {
            reference = FindReference(reference);
            object value;
            if (Values.TryGetValue(reference, out value))
                return (T) value;
            return default(T);
        }

        public IReference AddReference(IReference reference)
        {
            return References[reference.Name] = reference;
        }

        private IReference FindReference(IReference reference)
        {
            IReference value;
            if (References.TryGetValue(reference.Name, out value))
                return value;
            throw new ArgumentException("Reference not found at runtime: " + reference.Name);
        }

        public T GetValue<T>(Reference<T> reference)
        {
            return GetValue<T>((IReference)reference);
        }

        public void SetValue<T>(IReference reference, T value)
        {
            Values[FindReference(reference)] = value; // ok the extra lookup seems silly, but could catch certain code bugs
        }

        public void AddAndSetValue<T>(IReference reference, T value)
        {
            Values[AddReference(reference)] = value;
        }
    }
}
